#pragma once
#include "feDefs.h"
#include "feVector.h"
#include "feMatrix.h"

class feBordCond
{
public:
	virtual int  Type() = 0;
	virtual void AddToSlae(feMatrix *ioM, feVector *ioF, int iLayerNum=-1) = 0;
};


//-------------------------------------------------------------------------------------------------------------------------------------------
class feThirdBordCond1d : public feBordCond
{
	double Betha;
	double Ubetha;
	int	   Node;

public:
	feThirdBordCond1d()											{ Betha = 0; Ubetha = 0; Node = 0; }
	feThirdBordCond1d(int iNode, double iBetha, double iUbetha) { Node = iNode; Betha = iBetha; Ubetha = iUbetha; }
	virtual int  Type()											{ return 3; }
	virtual void AddToSlae(feMatrix *ioM, feVector *ioF, int iLayerNum=-1)		{ (*ioM->_IJ(Node, Node)) += Betha;	ioF->Data[Node] += Betha*Ubetha; }
};


//-------------------------------------------------------------------------------------------------------------------------------------------
class feSecondBordCond1d : public feBordCond
{
	double Theta;
	int	   Node;

public:
	feSecondBordCond1d()										{ Theta = 0; Node = 0; }
	feSecondBordCond1d(int iNode, double iTheta)				{ Node = iNode; Theta = iTheta; }
	virtual int  Type()											{ return 2; }
	virtual void AddToSlae(feMatrix *ioM, feVector *ioF, int iLayerNum=-1)		{ ioF->Data[Node] += Theta; }
};


//-------------------------------------------------------------------------------------------------------------------------------------------
class feSecondBordCondVec1d : public feBordCond
{
	feVector *Values;
	double	  Coeff;
	int	   Node;

public:
	feSecondBordCondVec1d() {}
	feSecondBordCondVec1d(int iNode, feVector *iValues, double iCoeff)	{ Node = iNode; Values = iValues; Coeff = iCoeff; }
	virtual int  Type()											{ return 2; }
	virtual void AddToSlae(feMatrix *ioM, feVector *ioF, int iLayerNum=-1)		{ ioF->Data[Node] += Values->Data[iLayerNum]*Coeff; }
};


//-------------------------------------------------------------------------------------------------------------------------------------------
class feFirstBordCond1d : public feBordCond
{
	double Value;
	int	   Node;

public:
	feFirstBordCond1d()										{ Value = 0; Node = 0; }
	feFirstBordCond1d(int iNode, double iValue)				{ Node = iNode; Value = iValue; }
	virtual int  Type()										{ return 1; }
	virtual void AddToSlae(feMatrix *ioM, feVector *ioF, int iLayerNum=-1)	{ static const double bignum = 1e40; (*ioM->_IJ(Node, Node)) = bignum; ioF->Data[Node] = Value*bignum; }
};


//-------------------------------------------------------------------------------------------------------------------------------------------
class feFirstBordCondVec1d : public feBordCond
{
	feVector *Values;
	int		  Node;
	double	  Coeff;

public:
	feFirstBordCondVec1d() {}
	feFirstBordCondVec1d(int iNode, feVector *iValues, double iCoeff)	{ Node = iNode; Values = iValues; Coeff = iCoeff; }
	virtual int  Type()									{ return 1; }
	virtual void AddToSlae(feMatrix *ioM, feVector *ioF, int iLayerNum)	
	{ 
		if(!Values || iLayerNum >= Values->GetSize()) return;
		static const double bignum = 1e40; 
		(*ioM->_IJ(Node, Node)) = bignum; 
		ioF->Data[Node] = Values->Data[iLayerNum] * Coeff * bignum; 
	}
};